package fun.ticsmyc.question.stringQuestion;

import org.junit.Test;

import java.util.Deque;
import java.util.LinkedList;

/**
 * @author Ticsmyc
 * @date 2021-03-08 9:35
 */
public class 基本计算器 {

    /**
     * 只包含 【数字 + - * / 和空格】 ， 没有括号
     * @param s
     * @return
     */
    public int easyCalculate(String s) {
        char[] str = s.toCharArray();
        int n = str.length;
        Deque<Integer> stack = new LinkedList<>();

        int num=0;
        char oper ='+';
        for(int i=0;i<str.length;++i){
            if(str[i]>='0' && str[i]<='9'){
                //如果是数字
                num = num*10 + (str[i]-'0');
            }
            //遇到操作符， 或者i到头了  先处理前面数字  然后修改操作
            if((!(str[i]>='0' && str[i]<='9') && str[i]!=' ') || i==s.length()-1){
                if(oper == '+'){
                    stack.push(num);
                }else if(oper == '-'){
                    stack.push(-num);
                }else if(oper == '*'){
                    stack.push(num * stack.pop());
                }else if(oper == '/'){
                    stack.push(stack.pop()/num);
                }
                num=0;
                oper = str[i];
            }
        }

        int res =0;
        while(!stack.isEmpty()){
            res += stack.pop();
        }
        return res;
    }


    /**
     * 包含括号、空格、数字、操作符
     * 递归思路： 遇到括号，去掉括号 递归计算
     * @param s
     * @return
     */
    public int hardCalculate(String s) {
        char[] str = s.toCharArray();
        int n = str.length;
        Deque<Integer> stack = new LinkedList<>();

        int num=0;
        char oper ='+';

        for(int i=0;i<str.length;++i){
            if(str[i]>='0'&&str[i]<='9'){
                num = num*10+(str[i]-'0');
            }else if(str[i]=='('){
                //找到与之对应的) 然后递归调用，得到num
                int cnt =1;
                int j=i+1;
                for(;j<str.length;++j){
                    if(str[j]=='('){
                        cnt++;
                    }else if(str[j]==')'){
                        cnt--;
                    }
                    if(cnt ==0){
                        break;
                    }
                }
                num = hardCalculate(s.substring(i+1,j));
                i=j;
            }
            if(i==str.length-1 ||  str[i]=='+' || str[i]=='-' || str[i]=='*' || str[i]=='/'){
                //遇到操作符
                if(oper == '+'){
                    stack.push(num);
                }else if(oper == '-'){
                    stack.push(-num);
                }else if(oper == '*'){
                    stack.push(num * stack.pop());
                }else if(oper == '/'){
                    stack.push(stack.pop()/num);
                }
                num=0;
                oper = str[i];
            }
        }
        int res =0;
        while(!stack.isEmpty()){
            res += stack.pop();
        }
        return res;
    }


    public int calculate(String s){
        char[] str= s.toCharArray();
        Deque<Integer> stack = new LinkedList<>();

        int num =0;
        int result =0;
        int sign =1;

        for(int i=0;i<str.length;++i){
            if(Character.isDigit(str[i])){
                num = num*10 + (str[i]-'0');
            }else if(str[i] =='+'){
                result += sign*num;  //当场计算  不入栈
                sign=1;
                num=0;
            }else if(str[i]=='-'){
                result += sign*num;
                sign=-1;
                num=0;
            }else if(str[i]=='('){
                //记录前一阶段的最终值和 对下一阶段的操作符
                stack.push(result);
                stack.push(sign);
                //重置
                sign =1;
                result =0;
            }else if(str[i]==')'){
                result += sign*num;

                result *= stack.pop();//操作符
                result += stack.pop();//加上前一阶段结果
                num=0;
            }
        }
        return result +(sign*num);
    }

    @Test
    public void test1(){
        System.out.println(calculate("(1+(4+5+2)-3)+(6+8)"));
    }
}
